#ifndef MAPPER_H
#define MAPPER_H

#include <QDataStream>
#include <QtGlobal>

// Mapper的作用是将CPU、PPU申请的地址映射到卡带上
// 不同的映射方式，主要有：Horizontal、Vertical、OneScreen_Lo、OneScreen_Hi
enum MirrorMode { HORIZONTAL = 0, VERTICAL = 1, ONESCREEN_LO = 9, ONESCREEN_HI = 10 };

class Mapper
{
public:
    Mapper(quint8 rnum, quint8 vrnum) : rom_num(rnum), vrom_num(vrnum) {}
    virtual ~Mapper() {}

public:
    // CPU相关虚函数
    // 读写0x6000-0xffff地址的数据
    virtual quint32 cpu_read_addram(quint16 addr) = 0;
    virtual quint32 cpu_write_addram(quint16 addr, quint8 data) = 0;
    // prg: program
    virtual quint32 cpu_read_prg(quint16 addr) = 0;
    virtual quint32 cpu_write_prg(quint16 addr, quint8 data) = 0;

public:
    // PPU相关虚函数
    // 读写图案表，切换名称表的映射方式
    // pt: pattern table
    virtual quint32 ppu_read_pt(quint16 addr) = 0;
    virtual quint32 ppu_write_pt(quint16 addr, quint8 data) = 0;

public:
    // IRQ Interface(例如Mapper4将用到)
    virtual bool irqState() { return false; }
    virtual void irqClear() {}

    // Scanline Counting
    virtual void scanline() {}

public:
    // 存档
    virtual void write_to_stream(QDataStream &) = 0;
    // 读档
    virtual void read_from_stream(QDataStream &) = 0;

public:
    quint8 nametable_mirror; // 名称表映射方式
    quint8 addram[0x2000];   // 卡带附加RAM
    quint8 *character_ram_ptr; // 如果卡带上没有图案表的话，则新建一块8KB的ram作为图案表

    quint8 rom_num;  // 程序块数
    quint8 vrom_num; // 图案块数
};

#endif // MAPPER_H
